﻿using Onshi.POS.Modelo.Entidades;
using Onshi.POS.AccesoDatos.Interfaces;
using Onshi.POS.AccesoDatos;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Onshi.POS.Modelo.Entidades.Tipos;

namespace Onshi.POS.Repositorios
{
    public class RepositorioVendedores : RepositorioEntidad<Vendedor, Int32, IServicioDatosVendedores>
    {
        #region Constructores

        public RepositorioVendedores()
            : base()
        {
        }

        #endregion

        #region Atributos

        private RepositorioTiposComisionesVendedores repositorioTiposComisionesVendedores = new RepositorioTiposComisionesVendedores();
        private RepositorioRubrosVendedores repositorioRubrosVendedores = new RepositorioRubrosVendedores();
        private RepositorioTiposTelefonos repositorioTiposTelefonos = new RepositorioTiposTelefonos();
        private RepositorioTiposDomicilios repositorioTiposDomicilios = new RepositorioTiposDomicilios();
        private RepositorioBarrios repositorioBarrios = new RepositorioBarrios();
        private RepositorioCamposPersonalizadosVendedores repositorioCamposPersonalizadosVendedores = new RepositorioCamposPersonalizadosVendedores();

        #endregion

        #region Metodos

        public override Vendedor DevolverPorId(Int32 id)
        {
            return DevolverPorId(id, false);
        }

        public Vendedor DevolverPorCodigo(String codigo)
        {
            return DevolverPorCodigo(codigo, false);
        }

        public List<Vendedor> DevolverTodos()
        {
            return DevolverTodos(false);
        }

        public Vendedor DevolverPorId(Int32 id, Boolean incluirImagen)
        {
            var vendedor = entidades.Where(x => x.Id == id).FirstOrDefault();
            if (vendedor == null)
                using (var ds = servicioDatos.Vendedores_DevolverPorId(id, incluirImagen))
                    if (ds.Tables[0].Rows.Count > 0)
                    {
                        vendedor = FilaAEntidad(ds.Tables[0].Rows[0]);
                        vendedor.Domicilios = TablaAListaDomicilios(ds.Tables[1]);
                        vendedor.Telefonos = TablaAListaTelefonos(ds.Tables[2]);
                        vendedor.CamposPersonalizados = TablaAListaCamposPersonalizados(ds.Tables[3]);
                        entidades.Add(vendedor);
                    }
            return vendedor;
        }

        public Vendedor DevolverPorCodigo(String codigo, Boolean incluirImagen)
        {
            var vendedor = entidades.Where(x => x.Codigo == codigo).FirstOrDefault();
            if (vendedor == null)
                using (var ds = servicioDatos.Vendedores_DevolverPorCodigo(codigo, incluirImagen))
                    if (ds.Tables[0].Rows.Count > 0)
                    {
                        vendedor = FilaAEntidad(ds.Tables[0].Rows[0]);
                        vendedor.Domicilios = TablaAListaDomicilios(ds.Tables[1]);
                        vendedor.Telefonos = TablaAListaTelefonos(ds.Tables[2]);
                        vendedor.CamposPersonalizados = TablaAListaCamposPersonalizados(ds.Tables[3]);
                        entidades.Add(vendedor);
                    }
            return vendedor;
        }

        public List<Vendedor> DevolverTodos(Boolean incluirImagen)
        {
            using (var ds = servicioDatos.Vendedores_DevolverTodos(incluirImagen))
            {
                entidades = TablaALista(ds.Tables[0]);
                foreach (var vendedor in entidades)
                {
                    var domicilios = ds.Tables[1].AsEnumerable().Where(x => (Int32)x["IdVendedor"] == vendedor.Id).AsDataView().ToTable();
                    vendedor.Domicilios = TablaAListaDomicilios(domicilios);
                    var telefonos = ds.Tables[2].AsEnumerable().Where(x => (Int32)x["IdVendedor"] == vendedor.Id).AsDataView().ToTable();
                    vendedor.Telefonos = TablaAListaTelefonos(telefonos);
                    var camposPersonalizados = ds.Tables[3].AsEnumerable().Where(x => (Int32)x["IdVendedor"] == vendedor.Id).AsDataView().ToTable();
                    vendedor.CamposPersonalizados = TablaAListaCamposPersonalizados(camposPersonalizados);
                }
            }
            return entidades;
        }

        private List<DomicilioVendedor> TablaAListaDomicilios(DataTable tabla)
        {
            var domicilios = new List<DomicilioVendedor>();
            foreach (DataRow fila in tabla.Rows)
                domicilios.Add(FilaADomicilio(fila));
            return domicilios;
        }

        private List<TelefonoVendedor> TablaAListaTelefonos(DataTable tabla)
        {
            var telefonos = new List<TelefonoVendedor>();
            foreach (DataRow fila in tabla.Rows)
                telefonos.Add(FilaATelefono(fila));
            return telefonos;
        }

        private List<VendedorCampoPersonalizadoVendedor> TablaAListaCamposPersonalizados(DataTable tabla)
        {
            var camposPersonalizadosVendedores = repositorioCamposPersonalizadosVendedores.DevolverTodos();
            var vendedoresCamposPersonalizadosVendedores = new List<VendedorCampoPersonalizadoVendedor>();
            foreach (DataRow fila in tabla.Rows)
                vendedoresCamposPersonalizadosVendedores.Add(FilaACampoPersonalizado(fila));
            foreach (var item in camposPersonalizadosVendedores)
                if (!vendedoresCamposPersonalizadosVendedores.Exists(x => x.Entidad.Id == item.Id))
                    vendedoresCamposPersonalizadosVendedores.Add(new VendedorCampoPersonalizadoVendedor()
                    {
                        Entidad = item,
                        Valor = String.Empty
                    });
            return vendedoresCamposPersonalizadosVendedores;
        }

        private DomicilioVendedor FilaADomicilio(DataRow fila)
        {
            var domicilio = new DomicilioVendedor();
            domicilio.Id = (Int32)fila["IdDomicilioVendedor"];
            domicilio.Calle = (String)fila["Calle"];
            domicilio.Numero = (String)fila["Numero"];
            domicilio.Piso = (String)fila["Piso"];
            domicilio.Departamento = (String)fila["Departamento"];
            domicilio.Tipo = repositorioTiposDomicilios.DevolverPorId((Byte)fila["IdTipoDomicilio"]);
            domicilio.Barrio = repositorioBarrios.DevolverPorId((Int32)fila["IdBarrio"]);
            return domicilio;
        }

        private TelefonoVendedor FilaATelefono(DataRow fila)
        {
            var telefono = new TelefonoVendedor();
            telefono.Id = (Int32)fila["IdTelefonoVendedor"];
            telefono.CodigoArea = (String)fila["CodigoArea"];
            telefono.Numero = (String)fila["Numero"];
            telefono.Tipo = repositorioTiposTelefonos.DevolverPorId((Byte)fila["IdTipoTelefono"]);
            return telefono;
        }

        private VendedorCampoPersonalizadoVendedor FilaACampoPersonalizado(DataRow fila)
        {
            var campoPersonalizado = new VendedorCampoPersonalizadoVendedor();
            campoPersonalizado.Valor = (String)fila["Valor"];
            campoPersonalizado.Entidad = repositorioCamposPersonalizadosVendedores.DevolverPorId((Int32)fila["IdCampoPersonalizadoVendedor"]);
            return campoPersonalizado;
        }

        public void Insertar(Vendedor vendedor)
        {
            vendedor.Id = servicioDatos.Vendedores_Insertar(vendedor.Rubro.Id, vendedor.TipoComision.Id, vendedor.Codigo, vendedor.Nombre, vendedor.Comision, vendedor.ComisionMaxima, vendedor.Email, vendedor.SitioWeb, vendedor.Observaciones, vendedor.Imagen);
        }

        public void Modificar(Vendedor vendedor)
        {
            servicioDatos.Vendedores_Modificar(vendedor.Id, vendedor.Rubro.Id, vendedor.TipoComision.Id, vendedor.Codigo, vendedor.Nombre, vendedor.Comision, vendedor.ComisionMaxima, vendedor.Email, vendedor.SitioWeb, vendedor.Observaciones, vendedor.Imagen, vendedor.EstaEliminado);
        }

        public void InsertarDomicilio(Vendedor vendedor, DomicilioVendedor domicilio)
        {
            domicilio.Id = servicioDatos.DomiciliosVendedores_Insertar(vendedor.Id, domicilio.Tipo.Id, domicilio.Barrio.Id, domicilio.Calle, domicilio.Numero, domicilio.Piso, domicilio.Departamento);
        }

        public void EliminarDomiciliosPorVendedor(Vendedor vendedor)
        {
            servicioDatos.DomiciliosVendedores_EliminarPorVendedor(vendedor.Id);
        }

        public void InsertarTelefono(Vendedor vendedor, TelefonoVendedor telefono)
        {
            telefono.Id = servicioDatos.TelefonosVendedores_Insertar(vendedor.Id, telefono.Tipo.Id, telefono.CodigoArea, telefono.Numero);
        }

        public void EliminarTelefonosPorVendedor(Vendedor vendedor)
        {
            servicioDatos.TelefonosVendedores_EliminarPorVendedor(vendedor.Id);
        }

        public void EliminarCamposPersonalizadosPorVendedor(Vendedor vendedor)
        {
            servicioDatos.VendedoresCamposPersonalizadosVendedores_EliminarPorVendedor(vendedor.Id);
        }

        public void InsertarCampoPersonalizado(Vendedor vendedor, VendedorCampoPersonalizadoVendedor campoPersonalizado)
        {
            servicioDatos.VendedoresCamposPersonalizadosVendedores_Insertar(vendedor.Id, campoPersonalizado.Entidad.Id, campoPersonalizado.Valor);
        }

        protected override Vendedor FilaAEntidad(DataRow fila)
        {
            var vendedor = new Vendedor();
            vendedor.Id = (Int32)fila["IdVendedor"];
            vendedor.Codigo = (String)fila["Codigo"];
            vendedor.Nombre = (String)fila["Nombre"];
            vendedor.Comision = (Decimal)fila["Comision"];
            vendedor.ComisionMaxima = (Decimal)fila["ComisionMaxima"];
            vendedor.Email = (String)fila["Email"];
            vendedor.SitioWeb = (String)fila["SitioWeb"];
            vendedor.Observaciones = (String)fila["Observaciones"];
            if (fila["Imagen"] != DBNull.Value)
                vendedor.Imagen = (Byte[])fila["Imagen"];
            vendedor.EstaEliminado = (Boolean)fila["EstaEliminado"];
            vendedor.TipoComision = repositorioTiposComisionesVendedores.DevolverPorId((Byte)fila["IdTipoComisionVendedor"]);
            vendedor.Rubro = repositorioRubrosVendedores.DevolverPorId((Int32)fila["IdRubroVendedor"]);
            return vendedor;
        }

        public void EliminarCamposPersonalizadosPorCampoPersonalizado(CampoPersonalizadoVendedor campoPersonalizadoVendedor)
        {
            servicioDatos.VendedoresCamposPersonalizadosVendedores_EliminarPorCampoPersonalizadoVendedor(campoPersonalizadoVendedor.Id);
        }

        public void ModificarBarrioEnDomicilios(Barrio barrioNuevo, Barrio barrioViejo)
        {
            servicioDatos.DomiciliosVendedores_ModificarBarrio(barrioNuevo.Id, barrioViejo.Id);
        }

        public void ModificarRubroProveedor(RubroVendedor rubroNuevo, RubroVendedor rubroViejo)
        {
            servicioDatos.Vendedores_ModificarRubroVendedor(rubroNuevo.Id, rubroViejo.Id);
        }

        #endregion
    }
}
